home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-11-05 | 20.8 KB | 1,062 lines | [TEXT/CWIE] |
- /*********************************************************************
- Project : GUSI - Grand Unified Socket Interface
- File : GUSIAppleTalk.cp - Appletalk Sockets
- Author : Matthias Neeracher
- Language : MPW C/C++
-
- $Log: GUSIAppletalk.cp,v $
- Revision 1.4 1994/12/30 19:37:23 neeri
- Wake up process on completion to improve performance.
-
- Revision 1.3 1994/08/10 00:31:28 neeri
- Sanitized for universal headers.
-
- Revision 1.2 1994/05/01 23:29:28 neeri
- Enable recvfrom with non-NULL from address.
-
- Revision 1.1 1994/02/25 02:28:11 neeri
- Initial revision
-
- Revision 0.18 1993/12/30 00:00:00 neeri
- Fiddle with select()
-
- Revision 0.17 1993/11/17 00:00:00 neeri
- Delay opening AppleTalk services
-
- Revision 0.16 1993/09/01 00:00:00 neeri
- Throw out nonbreaking spaces
-
- Revision 0.15 1993/02/07 00:00:00 neeri
- New configuration technique
-
- Revision 0.14 1993/01/17 00:00:00 neeri
- Handle user interrupts more carefully.
-
- Revision 0.13 1992/12/07 00:00:00 neeri
- Use flags
-
- Revision 0.12 1992/10/05 00:00:00 neeri
- I was a teenage NBP werewolf
-
- Revision 0.11 1992/09/13 00:00:00 neeri
- Always complete write
-
- Revision 0.10 1992/09/07 00:00:00 neeri
- Implement ioctl()
-
- Revision 0.9 1992/08/10 00:00:00 neeri
- Improve select()
-
- Revision 0.8 1992/07/28 00:00:00 neeri
- Separate creating symaddrs from registering them
-
- Revision 0.7 1992/07/26 00:00:00 neeri
- Error in using memccpy()
-
- Revision 0.6 1992/07/21 00:00:00 neeri
- Support symbolic addresses
-
- Revision 0.5 1992/07/13 00:00:00 neeri
- Make AppleTalkSockets available to other socket classes.
-
- Revision 0.4 1992/05/18 00:00:00 neeri
- Out of band data
-
- Revision 0.3 1992/05/18 00:00:00 neeri
- Basic functions work
-
- Revision 0.2 1992/05/12 00:00:00 neeri
- NBP stuff
-
- Revision 0.1 1992/05/10 00:00:00 neeri
- ADSPStreams
-
- *********************************************************************/
-
- #include "GUSI_P.h"
-
- #include <Errors.h>
- #include <ADSP.h>
- #include <Devices.h>
- #include <GestaltEqu.h>
- #include <PLStringFuncs.h>
- #include <LowMem.h>
-
- #include <Strings.h>
-
- #include <sys/types.h>
-
- class AtlkSymAddr;
-
- class AppleTalkSocketDomain : public SocketDomain {
- short dspRefNum;
-
- void DoMPPOpen();
- public:
- AppleTalkSocketDomain();
-
- AddrBlock node;
-
- short GetDSP();
- Boolean Validate();
- virtual Socket * socket(int type, short protocol);
- virtual int choose(
- int type,
- char * prompt,
- void * constraint,
- int flags,
- void * name,
- int * namelen);
- };
-
- class AppleTalkSocket : public Socket { // That's what this file's all about
- friend class AppleTalkSocketDomain;
- protected:
- Boolean nonblocking;
- Boolean ownSocket;
- Boolean readShutDown;
- Boolean writeShutDown;
- u_char socket;
- AddrBlock peer;
- AtlkSymAddr * symaddr;
-
- AppleTalkSocket(u_char sock = 0);
-
- virtual ~AppleTalkSocket();
-
- #if !GENERATINGCFM
- friend pascal void ADSPCompletion68K();
- Ptr processA5; /* Our A5 world */
- #endif
- public:
- virtual int bind(void * name, int namelen);
- virtual int getsockname(void * name, int * namelen);
- virtual int getpeername(void *name, int *namelen);
- virtual int fcntl(unsigned int cmd, int arg);
- virtual int ioctl(unsigned int request, void *argp);
- void Ready();
- };
-
- struct ADSPSockBuffers {
- enum {qSize = 4150};
-
- u_char attnBuf[attnBufSize];
- u_char sendBuf[qSize];
- u_char recvBuf[qSize];
- };
-
- typedef ADSPSockBuffers * ADSPBufPtr;
-
- class ADSPSocket;
-
- #if PRAGMA_ALIGN_SUPPORTED
- #pragma options align=mac68k
- #endif
- struct AnnotatedADSPParamBlock : public DSPParamBlock {
- AnnotatedADSPParamBlock(ADSPSocket * owner) : sock(owner) { };
-
- ADSPSocket * sock;
- };
- #if PRAGMA_ALIGN_SUPPORTED
- #pragma options align=reset
- #endif
-
- class ADSPSocket : public AppleTalkSocket {
- friend class AppleTalkSocketDomain;
-
- ADSPSocket(u_char sock = 0);
-
- TRCCB * ccb;
- DSPPBPtr pb;
- ADSPBufPtr bufs;
-
- int Init();
- void UnInit(Boolean abort);
- Boolean Waiting();
- Boolean Up();
- public:
- virtual int listen(int qlen);
- virtual int connect(void * address, int addrlen);
- virtual Socket * accept(void * address, int * addrlen);
- virtual int recvfrom(void * buffer, int buflen, int flags, void * from, int * fromlen);
- virtual int sendto(void * buffer, int buflen, int flags, void * to, int tolen);
- virtual int shutdown(int how);
- virtual int ioctl(unsigned int request, void *argp);
- virtual int select(Boolean * canRead, Boolean * canWrite, Boolean * exception);
-
- virtual ~ADSPSocket();
- };
-
- class AtlkSymAddr {
- NamesTableEntry * nte;
- Boolean legit;
- public:
- AtlkSymAddr(const EntityName & name);
-
- ~AtlkSymAddr();
-
- void Register(u_char socket);
- };
-
- int AtlkLookup(const EntityName & name, AddrBlock * addr);
-
- AppleTalkSocketDomain AppleTalkSockets;
- const AddrBlock NoFilter = {0, 0, 0};
-
- /************************ AppleTalkSocket members ************************/
-
- AppleTalkSocket::AppleTalkSocket(u_char sock)
- {
- socket = sock;
- ownSocket = !sock;
- nonblocking = false;
- readShutDown = false;
- writeShutDown = false;
- symaddr = nil;
- peer = NoFilter;
-
- #if !GENERATINGCFM
- processA5 = LMGetCurrentA5();
- #endif
- }
-
-
- inline void AppleTalkSocket::Ready()
- {
- AppleTalkSockets.Ready();
- }
-
- AppleTalkSocket::~AppleTalkSocket()
- {
- if (socket && ownSocket) {
- MPPParamBlock mpp;
-
- mpp.DDP.socket = socket;
-
- PCloseSkt(&mpp, false);
- }
-
- if (symaddr)
- delete symaddr;
- }
-
- int AppleTalkSocket::fcntl(unsigned int cmd, int arg)
- {
- switch (cmd) {
- case F_GETFL:
- if (nonblocking)
- return FNDELAY;
- else
- return 0;
- case F_SETFL:
- if (arg & FNDELAY)
- nonblocking = true;
- else
- nonblocking = false;
-
- return 0;
- default:
- return GUSI_error(EOPNOTSUPP);
- }
- }
-
- int AppleTalkSocket::ioctl(unsigned int request, void *argp)
- {
- switch (request) {
- case FIONBIO:
- nonblocking = (Boolean) *(long *) argp;
-
- return 0;
- default:
- return GUSI_error(EOPNOTSUPP);
- }
- }
-
- int AppleTalkSocket::bind(void *sa_name, int)
- {
-
- switch (*(short *) sa_name) {
- case AF_APPLETALK:
- {
- struct sockaddr_atlk * addr = (struct sockaddr_atlk *) sa_name;
-
- if (socket || !addr->addr.aSocket)
- return GUSI_error(EINVAL);
-
- socket = addr->addr.aSocket;
- ownSocket = false;
- }
- break;
- case ATALK_SYMADDR:
- {
- struct sockaddr_atlk_sym * addr = (struct sockaddr_atlk_sym *) sa_name;
-
- symaddr = new AtlkSymAddr(addr->name);
-
- if (errno) {
- delete symaddr;
- symaddr = nil;
-
- return -1;
- }
- }
- break;
- default:
- return GUSI_error(EAFNOSUPPORT);
- }
-
- return 0;
- }
-
- int AppleTalkSocket::getsockname(void *name, int *namelen)
- {
- struct sockaddr_atlk addr;
-
- addr.family = AF_APPLETALK;
- addr.addr = AppleTalkSockets.node;
- addr.addr.aSocket = socket;
-
- memcpy(name, &addr, *namelen = min(*namelen, int(sizeof(struct sockaddr_atlk))));
-
- return 0;
- }
-
- int AppleTalkSocket::getpeername(void *name, int *namelen)
- {
- struct sockaddr_atlk addr;
-
- if (!peer.aNet && !peer.aNode && !peer.aSocket)
- return GUSI_error(ENOTCONN);
-
- addr.family = AF_APPLETALK;
- addr.addr = peer;
-
- memcpy(name, &addr, *namelen = min(*namelen, int(sizeof(struct sockaddr_atlk))));
-
- return 0;
- }
-
- /********************* ADSPSocket members *********************/
-
- void ADSPCompletion(AnnotatedADSPParamBlock * pb)
- {
- pb->sock->Ready();
- }
-
- #if !GENERATINGCFM
- #ifdef __MWERKS__
- AnnotatedADSPParamBlock * GetADSPInfo() : __D0 = 0x2008; // MOVE.L A0,D0
- #else
- AnnotatedADSPParamBlock * GetADSPInfo() = 0x2008; // MOVE.L A0,D0
- #endif
-
- pascal void ADSPCompletion68K()
- {
- AnnotatedADSPParamBlock * pb = GetADSPInfo();
- long saveA5 = SetA5(long(pb->sock->processA5));
-
- ADSPCompletion(pb);
-
- SetA5(saveA5);
- }
-
- #define uADSPCompletion ADSPCompletion68K
-
- #else
- RoutineDescriptor uADSPCompletion =
- BUILD_ROUTINE_DESCRIPTOR(uppADSPCompletionProcInfo, ADSPCompletion);
- #endif
-
- ADSPSocket::ADSPSocket(u_char sock)
- : AppleTalkSocket(sock)
- {
- ccb = nil;
- pb = nil;
- bufs = nil;
-
- if (!AppleTalkSockets.GetDSP())
- GUSI_error(EPFNOSUPPORT); // Just an educated guess
- }
-
- ADSPSocket::~ADSPSocket()
- {
- UnInit(false);
- }
-
- inline Boolean ADSPSocket::Waiting()
- {
- return pb->ioResult == 1 && !(ccb->userFlags & (eClosed | eTearDown));
- }
-
- inline Boolean ADSPSocket::Up()
- {
- return !(ccb->userFlags & (eClosed | eTearDown));
- }
-
- int ADSPSocket::listen(int)
- {
- if (ccb)
- return GUSI_error(EISCONN);
-
- ccb = new TRCCB;
- if (!ccb)
- goto memErrCCB;
-
- pb = new AnnotatedADSPParamBlock(this);
- if (!pb)
- goto memErrPB;
-
- pb->ioCRefNum = AppleTalkSockets.GetDSP();
- pb->csCode = dspCLInit;
- pb->u.initParams.ccbPtr = ccb;
- pb->u.initParams.localSocket = socket;
-
- if (PBControlSync(ParmBlkPtr(pb)))
- goto memErr;
-
- socket = pb->u.initParams.localSocket;
-
- if (symaddr)
- symaddr->Register(socket);
-
- pb->csCode = dspCLListen;
- pb->ioCompletion = ADSPCompletionUPP(&uADSPCompletion);
- pb->u.openParams.filterAddress = NoFilter;
-
- PBControlAsync(ParmBlkPtr(pb));
-
- return 0;
-
- memErr:
- delete pb;
- pb = nil;
- memErrPB:
- delete ccb;
- ccb = nil;
- memErrCCB:
- return GUSI_error(ENOMEM);
- }
-
- int ADSPSocket::Init()
- {
- if (ccb)
- if (pb->csCode == dspOpen && pb->ioResult && pb->ioResult != 1)
- return 0; // Second chance for lose on open
- else
- return GUSI_error(EISCONN); // Got a live un', don't reconnect
-
- ccb = new TRCCB;
- if (!ccb)
- goto memErrCCB;
-
- pb = new AnnotatedADSPParamBlock(this);
- if (!pb)
- goto memErrPB;
-
- bufs = new ADSPSockBuffers;
- if (!bufs)
- goto memErrBufs;
-
- pb->ioCRefNum = AppleTalkSockets.GetDSP();
- pb->csCode = dspInit;
- pb->u.initParams.ccbPtr = ccb;
- pb->u.initParams.userRoutine = nil;
- pb->u.initParams.sendQSize = bufs->qSize;
- pb->u.initParams.sendQueue = bufs->sendBuf;
- pb->u.initParams.recvQSize = bufs->qSize;
- pb->u.initParams.recvQueue = bufs->recvBuf;
- pb->u.initParams.attnPtr = bufs->attnBuf;
- pb->u.initParams.localSocket = socket;
-
- if (!PBControlSync(ParmBlkPtr(pb))) {
- socket = pb->u.initParams.localSocket;
-
- if (symaddr)
- symaddr->Register(socket);
-
- return 0;
- }
-
- delete bufs;
- bufs = nil;
- memErrBufs:
- delete pb;
- pb = nil;
- memErrPB:
- delete ccb;
- ccb = nil;
- memErrCCB:
- return GUSI_error(ENOMEM);
- }
-
- void ADSPSocket::UnInit(Boolean abort)
- {
- if (ccb && pb) {
- pb->csCode = bufs ? dspRemove : dspCLRemove;
- pb->u.closeParams.abort = abort;
-
- PBControlSync(ParmBlkPtr(pb));
- }
-
- if (ccb)
- delete ccb;
- if (pb)
- delete pb;
- if (bufs)
- delete bufs;
-
- ccb = nil;
- pb = nil;
- bufs = nil;
- }
-
- int ADSPSocket::connect(void *sa_name, int)
- {
- switch (*(short *) sa_name) {
- case AF_APPLETALK:
- {
- sockaddr_atlk * addr = (struct sockaddr_atlk *) sa_name;
- peer = addr->addr;
- }
- break;
- case ATALK_SYMADDR:
- {
- struct sockaddr_atlk_sym * addr = (struct sockaddr_atlk_sym *) sa_name;
-
- if (AtlkLookup(addr->name, &peer))
- return -1;
- }
- break;
- default:
- return GUSI_error(EAFNOSUPPORT);
- }
-
- if (Init())
- return -1;
-
- pb->csCode = dspOpen;
- pb->ioCompletion = ADSPCompletionUPP(&uADSPCompletion);
- pb->u.openParams.remoteAddress = peer;
- pb->u.openParams.filterAddress = NoFilter;
- pb->u.openParams.ocMode = ocRequest;
- pb->u.openParams.ocInterval = 0;
- pb->u.openParams.ocMaximum = 0;
-
- PBControlAsync(ParmBlkPtr(pb));
-
- if (nonblocking)
- return GUSI_error(EINPROGRESS);
-
- SAFESPIN(Waiting(), SP_MISC, 0);
-
- if (errno) {
- UnInit(true);
-
- return -1;
- } else if (pb->ioResult == noErr) {
- return 0;
- } else
- return GUSI_error(ECONNREFUSED);
- }
-
- Socket * ADSPSocket::accept(void * address, int * addrlen)
- {
- ADSPSocket * newsock;
- sockaddr_atlk addr;
-
- if (!pb || pb->csCode != dspCLListen)
- return (Socket *) GUSI_error_nil(ENOTCONN);
-
- if (nonblocking && pb->ioResult == 1)
- return (Socket *) GUSI_error_nil(EWOULDBLOCK);
-
- SPINP(Waiting(), SP_MISC, 0);
-
- if (pb->ioResult)
- return (Socket *) GUSI_error_nil(EINVAL);
-
- newsock = new ADSPSocket(socket);
-
- if (!newsock)
- return (Socket *) GUSI_error_nil(ENOMEM);
- if (newsock->Init())
- return (Socket *) nil;
-
- newsock->pb->csCode = dspOpen;
- newsock->pb->ioCompletion = ADSPCompletionUPP(&uADSPCompletion);
- newsock->pb->u.openParams = pb->u.openParams;
- newsock->pb->u.openParams.ocMode = ocAccept;
- newsock->pb->u.openParams.ocInterval = 0;
- newsock->pb->u.openParams.ocMaximum = 0;
- PBControlAsync(ParmBlkPtr(newsock->pb));
-
- SAFESPIN(newsock->Waiting(), SP_MISC, 0);
-
- pb->csCode = dspCLListen;
- pb->ioCompletion = ADSPCompletionUPP(&uADSPCompletion);
- pb->u.openParams.filterAddress = NoFilter;
-
- PBControlAsync(ParmBlkPtr(pb));
-
- if (errno || newsock->pb->ioResult) {
- delete newsock;
-
- return (Socket *) (errno ? nil : GUSI_error_nil(ECONNREFUSED));
- }
-
- if (address && addrlen) {
- addr.family = AF_APPLETALK;
- addr.addr = pb->u.openParams.remoteAddress;
-
- memcpy(address, &addr, *addrlen = min(*addrlen, int(sizeof(sockaddr_atlk))));
- }
-
- return newsock;
- }
-
- int ADSPSocket::recvfrom(void * buffer, int buflen, int flags, void * from, int * fromlen)
- {
- // To avoid blocking in the ADSP driver, if no data is available, we only read
- // 1 byte and then the rest of the segment that has arrived
-
- int trylen;
- int actlen;
-
- if (from)
- getpeername(from, fromlen);
- if (flags & ~MSG_OOB)
- return GUSI_error(EOPNOTSUPP);
- if (!pb)
- return GUSI_error(ENOTCONN);
-
- if (pb->csCode == dspOpen && pb->ioResult) {
- if (pb->ioResult == 1) {
- if (nonblocking)
- return GUSI_error(EWOULDBLOCK);
-
- SPIN(Waiting(), SP_MISC, 0);
- }
-
- if (pb->ioResult)
- return GUSI_error(ECONNREFUSED);
- }
-
- if (flags & MSG_OOB)
- if (ccb->userFlags & eAttention) {
- memcpy(Ptr(buffer), ccb->attnPtr, buflen = min(buflen, ccb->attnSize));
-
- ccb->userFlags ^= eAttention;
-
- return buflen;
- } else
- return GUSI_error(EINVAL);
-
- pb->csCode = dspStatus;
-
- PBControlSync(ParmBlkPtr(pb));
-
- if (pb->u.statusParams.recvQPending)
- trylen = pb->u.statusParams.recvQPending;
- else
- if (nonblocking)
- return GUSI_error(EWOULDBLOCK);
- else if (readShutDown)
- return 0;
- else
- trylen = 1;
-
- while (!pb->u.statusParams.recvQPending && Up()) {
- SPIN(0, SP_STREAM_READ, 0);
- PBControlSync(ParmBlkPtr(pb));
- }
-
- pb->csCode = dspRead;
- pb->ioCompletion = ADSPCompletionUPP(&uADSPCompletion);
- pb->u.ioParams.reqCount = min(buflen, trylen);
- pb->u.ioParams.dataPtr = (u_char *) buffer;
-
- PBControlAsync(ParmBlkPtr(pb));
-
- SPIN(Waiting(), SP_STREAM_READ, 0);
-
- actlen = pb->u.ioParams.actCount;
-
- if (pb->ioResult)
- readShutDown = true;
- else {
- buflen -= actlen;
-
- if (actlen == 1 && buflen) {
- pb->csCode = dspStatus;
-
- PBControlSync(ParmBlkPtr(pb));
-
- if (trylen = pb->u.statusParams.recvQPending) {
- pb->csCode = dspRead;
- pb->u.ioParams.reqCount = min(buflen, trylen);
- pb->u.ioParams.dataPtr = ((u_char *) buffer) + actlen;
-
- if (PBControlSync(ParmBlkPtr(pb)))
- readShutDown = true;
-
- actlen += pb->u.ioParams.actCount;
- }
- }
- }
-
- return actlen;
- }
-
- int ADSPSocket::sendto(void * buffer, int buflen, int flags, void * to, int)
- {
- if (to)
- return GUSI_error(EOPNOTSUPP);
- if (flags & ~MSG_OOB)
- return GUSI_error(EOPNOTSUPP);
- if (!pb)
- return GUSI_error(ENOTCONN);
-
- if (pb->csCode == dspOpen && (pb->ioResult || !Up())) {
- if (Waiting()) {
- if (nonblocking)
- return GUSI_error(EWOULDBLOCK);
-
- SPIN(Waiting(), SP_MISC, 0);
- }
-
- if (pb->ioResult)
- return GUSI_error(ECONNREFUSED);
- }
-
- if (writeShutDown)
- return GUSI_error(ESHUTDOWN);
-
- if (flags & MSG_OOB) {
- if (buflen < 0 || buflen > 570)
- return GUSI_error(EINVAL);
-
- pb->csCode = dspAttention;
- pb->u.attnParams.attnCode = 0;
- pb->u.attnParams.attnSize = buflen;
- pb->u.attnParams.attnData = (unsigned char *) buffer;
-
- PBControlSync(ParmBlkPtr(pb));
-
- if (pb->ioResult)
- return GUSI_error(EINVAL);
- else
- return buflen;
- }
-
- if (nonblocking) {
- pb->csCode = dspStatus;
-
- PBControlSync(ParmBlkPtr(pb));
-
- if (!pb->u.statusParams.sendQFree)
- return GUSI_error(EWOULDBLOCK);
- }
-
- pb->csCode = dspWrite;
- pb->ioCompletion = ADSPCompletionUPP(&uADSPCompletion);
- pb->u.ioParams.reqCount =
- nonblocking
- ? min(buflen, pb->u.statusParams.sendQFree)
- : buflen;
- pb->u.ioParams.dataPtr = (u_char *) buffer;
- pb->u.ioParams.eom = false;
- pb->u.ioParams.flush = true;
-
- PBControlAsync(ParmBlkPtr(pb));
-
- SPIN(Waiting(), SP_STREAM_WRITE, 0);
-
- if (pb->ioResult)
- writeShutDown = true;
-
- return pb->u.ioParams.actCount;
- }
-
- int ADSPSocket::shutdown(int how)
- {
- if (how < 0 || how > 2)
- return GUSI_error(EINVAL);
-
- if (how)
- writeShutDown = true;
- if (!(how & 1))
- readShutDown = true;
-
- return 0;
- }
-
- int ADSPSocket::ioctl(unsigned int request, void *argp)
- {
- switch (request) {
- case FIONREAD:
- if (!pb)
- return GUSI_error(ENOTCONN);
-
- pb->csCode = dspStatus;
-
- PBControlSync(ParmBlkPtr(pb));
-
- *(unsigned long *) argp = pb->u.statusParams.recvQPending;
-
- return 0;
- default:
- return AppleTalkSocket::ioctl(request, argp);
- }
- }
-
- int ADSPSocket::select(Boolean * canRead, Boolean * canWrite, Boolean * exception)
- {
- int goodies = 0;
-
- if (pb) {
- pb->csCode = dspStatus;
- PBControlSync(ParmBlkPtr(pb));
- }
-
- if (canRead)
- if ( !pb || readShutDown || !Up() || pb->u.statusParams.recvQPending
- || (pb->csCode == dspCLListen && pb->ioResult != 1)
- ) {
- *canRead = true;
- ++goodies;
- }
-
- if (canWrite)
- if ( !pb || writeShutDown || !Up() || pb->u.statusParams.sendQFree != 0
- || (pb->csCode == dspOpen && pb->ioResult != 1)
- ) {
- *canWrite = true;
- ++goodies;
- }
-
- if (exception && (ccb->userFlags & eAttention)) {
- *exception = true;
- ++goodies;
- }
-
- return goodies;
- }
-
- /********************* AppleTalkSocketDomain members **********************/
-
- extern "C" void GUSIwithAppleTalkSockets()
- {
- AppleTalkSockets.DontStrip();
- }
-
- AppleTalkSocketDomain::AppleTalkSocketDomain()
- : SocketDomain(AF_APPLETALK)
- {
- dspRefNum = 0;
- node.aNet = 0xFFFF;
- node.aNode = 0;
- node.aSocket= 0;
- }
-
- void AppleTalkSocketDomain::DoMPPOpen()
- {
- short myNode;
- short myNet;
-
- if (AppleTalkIdentity(myNet, myNode)) {
- node.aNet = 0xFFFF;
- node.aNode = 0;
- node.aSocket= 0;
- } else {
- node.aNet = myNet;
- node.aNode = (u_char) myNode;
- node.aSocket= 1;
- }
- }
-
- Boolean AppleTalkSocketDomain::Validate()
- {
- if (!node.aSocket)
- DoMPPOpen();
-
- return node.aSocket != 0;
- }
-
- short AppleTalkSocketDomain::GetDSP()
- {
- if (!dspRefNum)
- if (OpenDriver((StringPtr) "\p.DSP", &dspRefNum))
- dspRefNum = 0;
-
- return dspRefNum;
- }
-
- Socket * AppleTalkSocketDomain::socket(int type, short)
- {
- AppleTalkSocket * sock = nil;
-
- errno = 0;
-
- if (!Validate())
- GUSI_error(ENETDOWN);
- else
- switch (type) {
- case SOCK_STREAM:
- sock = new ADSPSocket();
- break;
- default:
- GUSI_error(ESOCKTNOSUPPORT);
- }
-
- if (sock && errno) {
- delete sock;
-
- return nil;
- } else
- return sock;
- }
-
- int AppleTalkSocketDomain::choose(int, char * prompt, void * constraint, int flags, void * name, int * namelen)
- {
- sa_constr_atlk * constr = (sa_constr_atlk *) constraint;
- Point where;
- NBPReply reply;
- sockaddr_atlk addr;
- Str255 promp;
- NLType dummy;
-
- if (!hasStdNBP)
- return GUSI_error(EOPNOTSUPP);
-
- if (!Validate())
- return GUSI_error(ENETDOWN);
-
- if (flags & (CHOOSE_NEW | CHOOSE_DIR))
- return GUSI_error(EINVAL);
-
- SetPt(&where, 100, 100);
-
- memset(&reply.theEntity, 0, sizeof(EntityName));
- memcpy(&reply.theEntity.zoneStr, (StringPtr) "\p*", 2);
-
- CopyC2PStr(prompt, promp);
-
- if (
- StandardNBP(
- where,
- promp,
- constr ? constr->numTypes : -1,
- constr ? constr->types : dummy,
- NameFilterUPP(nil),
- ZoneFilterUPP(nil),
- DlgHookUPP(nil),
- &reply)
- != nlOk
- )
- return GUSI_error(EINTR);
-
- addr.family = AF_APPLETALK;
- addr.addr = reply.theAddr;
-
- memcpy(name, &addr, *namelen = min(*namelen, int(sizeof(sockaddr_atlk))));
-
- return 0;
- }
-
- /*********************** AtlkSymAddr members ************************/
-
- static int EntityLen(const EntityName & name)
- {
- Ptr nm = Ptr(&name);
- int l1 = *nm+1;
- nm += l1;
- int l2 = *nm+1;
- nm += l2;
- int l3 = *nm+1;
-
- return l1+l2+l3;
- }
-
- AtlkSymAddr::AtlkSymAddr(const EntityName & name)
- {
- int len = EntityLen(name);
-
- errno = 0;
-
- if (!AppleTalkSockets.Validate()) {
- GUSI_error(ENETDOWN);
-
- return;
- }
-
- nte = (NamesTableEntry *) NewPtr(9+len);
- legit = false;
-
- if (!nte) {
- GUSI_error(ENOMEM);
-
- return;
- }
-
- nte->qNext = nil;
- memcpy(&nte->nt.entityData, &name, len);
- }
-
- void AtlkSymAddr::Register(u_char socket)
- {
- MPPParamBlock mpp;
-
- errno = 0;
-
- nte->nt.nteAddress.aSocket = socket;
-
- mpp.NBPinterval = 8;
- mpp.NBPcount = 3;
- mpp.NBPntQElPtr = Ptr(nte);
- mpp.NBPverifyFlag = true;
- PRegisterName(&mpp, false);
-
- if (mpp.MPPioResult) {
- DisposPtr(Ptr(nte));
-
- GUSI_error((mpp.MPPioResult == nbpDuplicate) ? EADDRINUSE : EINVAL);
- } else
- legit = true;
- }
-
- AtlkSymAddr::~AtlkSymAddr()
- {
- if (nte) {
- if (legit) {
- MPPParamBlock mpp;
-
- mpp.NBPentityPtr = Ptr(&nte->nt.entityData);
- PRemoveName(&mpp, false);
- }
-
- DisposPtr(Ptr(nte));
- }
- }
-
- int AtlkLookup(const EntityName & name, AddrBlock * addr)
- {
- EntityName ent;
- char found[256];
- MPPParamBlock mpp;
-
- mpp.NBPinterval = 8;
- mpp.NBPcount = 3;
- mpp.NBPentityPtr = Ptr(&name);
- mpp.NBPretBuffPtr = found;
- mpp.NBPretBuffSize = 256;
- mpp.NBPmaxToGet = 1;
- PLookupName(&mpp, false);
- if (!mpp.MPPioResult)
- NBPExtract(found, mpp.NBPnumGotten, 1, &ent, addr);
-
- if (mpp.MPPioResult)
- return GUSI_error(ECONNREFUSED);
-
- return 0;
- }
-